package game.data;

import game.data.ABProjectData;
import haxe.DynamicAccess;
import echo.shape.Circle;
import echo.shape.Polygon;
import haxe.Json;
import game.data.IRoleData;

using Reflect;

/**
 * 项目导出器
 */
class ProjectDataExport {
	/**
	 * 编辑数据版本号
	 */
	public static var EDITER_DATA_VERSION:String = "1.0.1";

	/**
	 * 预备导出的数据
	 */
	public var data:IRoleData;

	public function new(data:IRoleData) {
		this.data = data;
	}

	public function mapToDynamic(map:Map<String, Dynamic>):Dynamic {
		if (map == null)
			return {};
		var obj:DynamicAccess<Dynamic> = {};
		for (key => value in map) {
			obj[key] = value;
		}
		return obj;
	}

	public function mapToActionData(map:Map<String, ActionData>):Dynamic<ABActionData> {
		if (map == null)
			return {};
		var obj:DynamicAccess<ABActionData> = {};
		for (key => value in map) {
			var data:ABActionData = {
				frames: arrayToFrameData(value.frames),
				name: value.name,
				desc: value.desc,
				mpConsume: value.mpConsume,
				hpConsume: value.hpConsume,
				effortConsume: value.effortConsume,
				cd: value.cd,
				fps: value.fps,
				type: value.type,
				allowAirMove: value.allowAirMove,
				diabledForce: value.diabledForce,
				groupKeys: value.groupKeys,
				airGravity: value.airGravity,
			};
			obj[key] = data;
		}
		return obj;
	}

	public function arrayToEffectData(array:Array<EffectData>):Array<ABEffectData> {
		if (array == null)
			return [];
		var obj:Array<ABEffectData> = [];
		for (value in array) {
			var data:ABEffectData = {
				x: value.x,
				y: value.y,
				script: value.script,
				scaleX: value.scaleX,
				scaleY: value.scaleY,
				rotation: value.rotation,
				fps: value.fps,
				displayName: value.displayName,
				name: value.name,
				blendMode: value.blendMode,
				sound: value.sound,
				liveTime: value.liveTime,
				speed: value.speed != null ? {
					x: value.speed.x,
					y: value.speed.y
				} : null,
				isFollow: value.isFollow,
				isLockAction: value.isLockAction,
				isFlyProp: value.isFlyProp,
				isHitClean: value.isHitClean,
				startFrame: value.startFrame,
				frames: arrayToFrameData(value.frames),
				isApplyColorTranform: value.isApplyColorTranform,
				R: value.R,
				G: value.G,
				B: value.B,
				ROffset: value.ROffset,
				GOffset: value.GOffset,
				BOffset: value.BOffset
			}
			obj.push(data);
		}
		return obj;
	}

	public function arrayToFrameData(array:Array<FrameData>):Dynamic {
		if (array == null)
			return [];
		var obj:Array<ABFrameData> = [];
		for (item in array) {
			var data:ABFrameData = {
				eventTag: item.eventTag,
				name: item.name,
				moveX: item.originMoveX,
				moveY: item.originMoveY,
				collision: null,
				collisionLiveTime: item.collisionLiveTime,
				hitData: null,
				isStop: item.isStop,
				stopAction: item.stopAction,
				effects: arrayToEffectData(item.effects),
				sound: item.sound,
				shareCollision: item.shareCollision,
				scaleY: item.originScaleY,
				scaleX: item.originScaleX,
				rotate: item.originRotate,
				pointX: item.originPointX,
				pointY: item.originPointY,
				alpha: item.originAlpha,
				shakeIntensity: item.shakeIntensity,
				shakeDuration: item.shakeDuration,
				shakeFrequency: item.shakeFrequency,
				invincibleTime: item.invincibleTime,
				stoicTime: item.stoicTime,
			};
			if (item.collision != null) {
				var result:Array<ABCollision> = [];
				for (shape in item.collision.shapes) {
					if (shape is Polygon) {
						var polygon:Polygon = cast shape;
						result.push({
							"type": "Polygon",
							"points": [
								for (vector in @:privateAccess polygon.local_vertices) {
									[vector.x, vector.y];
								}
							]
						});
					} else if (shape is Circle) {
						var circle:Circle = cast shape;
						result.push({
							"type": "Circle",
							"radius": circle.radius
						});
					}
				}
				data.collision = result;
			}
			if (item.hitData != null) {
				var result:ABHitData = {
					sound: item.hitData.sound,
					eventTag: item.hitData.eventTag,
					damageScale: item.hitData.damageScale,
					attackType: item.hitData.attackType,
					hitMoveX: item.hitData.hitMoveX,
					hitMoveY: item.hitData.hitMoveY,
					stiffenTime: item.hitData.stiffenTime,
					isBlow: item.hitData.isBlow,
					hitColor: "0x" + StringTools.hex(item.hitData.hitColor),
					createX: item.hitData.createX,
					createY: item.hitData.createY,
					isDestroyDefense: item.hitData.isDestroyDefense,
					isDefense: item.hitData.isDefense,
					stopFrameTimeEnemy: item.hitData.stopFrameTimeEnemy,
					stopFrameTimeSelf: item.hitData.stopFrameTimeSelf,
					applyRoleStopFrame: item.hitData.applyRoleStopFrame,
					hitEffectId: item.hitData.hitEffectId,
					hitBlowEffectId: item.hitData.hitBlowEffectId,
					attackInterval: item.hitData.attackInterval,
					maxTimes: item.hitData.maxTimes,
					shakeIntensity: item.hitData.shakeIntensity,
					shakeDuration: item.hitData.shakeDuration,
					shakeFrequency: item.hitData.shakeFrequency,
				};
				data.hitData = result;
			}
			obj.push(data);
		}
		return obj;
	}

	/**
	 * 导出格式
	 * @return String
	 */
	public function export():String {
		var abproj:ABProjectData = {
			eventTag: data.eventTag,
			// offestX: data.offestX,
			// offestY: data.offestY,
			offestConfig: data.offestConfig,
			atlas: data.atlas,
			actions: mapToActionData(data.actions),
			attrData: data.attrData,
			data: data.data,
			editerVersion: EDITER_DATA_VERSION,
			buildVersion: data.buildVersion,
		};
		return Json.stringify(abproj, "	");
	}
}
